feat(dpop,webmention,activitypub,mastodon-api): close near-term Anglesite feature gaps - #423
Conversation
Widen the allow-list the spec marked "not implemented yet — widen on demand": ES512 (P-521 + SHA-512) and EdDSA over RFC 8037 OKP keys, including the OKP RFC 7638 thumbprint. Ed448 stays rejected as crv_mismatch — the Workers runtime has no Web Crypto support for it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XT45PcE3pgXgsQffQDWdhW
Anglesite-app's consumer requires the field on every prefix claim (only a specification can approve child paths) and recommends it on exact claims; spec/catalog.md had tracked the back-fill as a follow-up. Every claim now carries it except webdav's /dav-credentials, a package-defined exact-claim admin endpoint with no governing external spec. The catalog gate now enforces the prefix-claim requirement mechanically. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XT45PcE3pgXgsQffQDWdhW
The spec's last known gap, a SHOULD: SendOptions gains an opt-in sentLog recording every accepted notification (createD1SentLog — own webmentions_sent table, strongly consistent), and resendForDeletedSource(source) re-sends to every recorded target once the source serves 410 Gone so receivers re-verify and drop the mention. Accepted (or endpoint-less) re-sends clear their log row; failed ones keep it for a later retry. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XT45PcE3pgXgsQffQDWdhW
Close the deferred phase-2 gap: #onFollow stores a new follower's Follow (or FEP-1b12 Group membership Join) in the actor's inbox — a re-Follow from a still-recorded follower is not a fresh notification — the __client/notifications classifier surfaces those rows, and notificationEntity maps them to Mastodon's type "follow" so clients like Tusky and Pixelfed see new-follower notifications. The inbox path also queues the follower's actor-profile fetch for name/avatar hydration. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XT45PcE3pgXgsQffQDWdhW
|
The The repo's own gates are passing on this head: Generated by Claude Code |
davidwkeith
left a comment
There was a problem hiding this comment.
Reviewed all four increments (@dwk/dpop EdDSA/ES512, catalog specificationURL backfill, @dwk/webmention deleted-source resend, @dwk/activitypub+@dwk/mastodon-api follow notifications) against the repo's architecture rules and CONTRIBUTING.md.
Code: No correctness or security issues found.
@dwk/dpop:ES512correctly pairs P-521/SHA-512;EdDSAcorrectly restricts tokty: "OKP"/crv: "Ed25519"(Ed448 rejected ascrv_mismatch, matching the documented Workers Web Crypto limitation).jwk.ktyis checked against the algorithm spec before any curve/signature check, so there's no algorithm-confusion opening. The OKP thumbprint canonicalization ({crv, kty, x}) matches RFC 8037 §3.2's required member order.@dwk/webmention:sent-log.ts's D1 table name is validated against/^[A-Za-z_][A-Za-z0-9_]*$/before being interpolated into DDL; all row values go through bound?1/?2/?3params — no injection surface.resendForDeletedSourcedelegates to the existingsendWebmention(already routed through@dwk/safe-fetch) rather than adding a new fetch path.@dwk/activitypub:#onFollow's new-follower check (SELECTbeforeINSERT OR IGNORE, then conditionally#storeInbox) has no await between the read and the write, so there's no TOCTOU race given the Durable Object's single-threaded request processing.- Verified independently: every
"match": "prefix"route in the resultingcatalog.jsonnow carries aspecificationURL(the one deliberate exact-claim exception,/dav-credentials, is correctly excluded per the gate rule added incatalog-gate.mjs).
Verification: Built a worktree off this branch and ran pnpm lint, pnpm format:check, pnpm build — all clean. pnpm test for the four touched packages passed (622/623 individually-verified; the one failure only reproduced under full-suite parallel load in my sandbox and passed cleanly in isolation — consistent with GitHub's own build-test check already being green on this PR).
CONTRIBUTING.md conformance: PR title/body match the Conventional Commits + template format, checklist is complete, changesets are present for all three publishable-package changes, and specs (dpop.md, catalog.md, webmention.md, mastodon-api.md) were updated in the same PR and accurately reflect the code.
Not a code issue, FYI: like #422, the github-advanced-security check failure here is GitHub's own Copilot agent hitting CAPIError: 400 model_not_supported, not a finding against this diff.
No changes requested.
Generated by Claude Code
Summary
Implements the tractable slice of a repo-wide sweep for optional/deferred spec requirements Anglesite is likely to request next — four independent increments:
@dwk/dpop—EdDSA(Ed25519) +ES512proof algorithms. The spec had marked both "not implemented yet — widen on demand"; this widens the allow-list with ES512 (P-521 + SHA-512) and EdDSA over RFC 8037 OKP keys, including the OKP RFC 7638 thumbprint. Ed448 stays rejected ascrv_mismatch(no Web Crypto support in the Workers runtime); symmetric algorithms andnoneremain excluded.specificationURLback-filled onto every route claim. Anglesite-app's consumer (WorkerRouteClaims.validate, Anglesite-app#829) requires the field on everyprefixclaim;spec/catalog.mdhad tracked the back-fill as a follow-up. All 27 remaining claims now carry it (the one deliberate exception:webdav's/dav-credentials, a package-defined exact-claim admin endpoint with no governing external spec), andscripts/catalog-gate.mjsnow enforces the prefix-claim requirement mechanically.@dwk/webmention— deleted-source re-send (§3.1.5, the spec's last known gap).SendOptionsgains an opt-insentLogrecording every accepted notification (createD1SentLog, ownwebmentions_senttable, strongly consistent per the non-functional rules), andresendForDeletedSource(source)re-sends to every recorded target once the source serves410 Gone, so receivers re-verify and drop the mention. Accepted (or endpoint-less) re-sends clear their log row; failed ones keep it for a later retry. Two new observability events.@dwk/activitypub+@dwk/mastodon-api—follownotifications (the deferred phase-2 gap).#onFollownow stores a new follower'sFollow(or FEP-1b12GroupmembershipJoin) in the actor's inbox — a re-Follow from a still-recorded follower is not a fresh notification — the__client/notificationsclassifier surfaces those rows, andnotificationEntitymaps them to Mastodon'stype: "follow", so clients like Tusky and Pixelfed see new-follower notifications (with actor-profile hydration for name/avatar via the existing queued fetch).Specs updated accordingly (
spec/packages/dpop.md,spec/catalog.md,spec/packages/webmention.md,spec/packages/mastodon-api.md).Packages affected
@dwk/dpop, @dwk/webmention, @dwk/activitypub, @dwk/mastodon-api (plus repo-root
catalog.json,scripts/catalog-gate.mjs, and specs)Checklist
spec/packages/and updated them ifbehaviour changed
src/*.test.ts)pnpm lint && pnpm format:check && pnpm typecheck && pnpm build && pnpm testpnpm changeset) if this touches a publishablepackage
catalog.json/conformance/status.jsonif this adds a newmountable worker or changes conformance status —
catalog.jsonroute claims back-filled; no new worker, conformance status unchanged🤖 Generated with Claude Code
https://claude.ai/code/session_01XT45PcE3pgXgsQffQDWdhW
Generated by Claude Code